#pragma once

#include  "iostream"
#include  "vector"
#include  "stack"
#include  "unordered_map"
#include   "queue"

using namespace std;

/*
 *907. 子数组的最小值之和
中等
626
相关企业
给定一个整数数组 arr，找到 min(b) 的总和，其中 b 的范围为 arr 的每个（连续）子数组。

由于答案可能很大，因此 返回答案模 10^9 + 7 。



示例 1：

输入：arr = [3,1,2,4]
输出：17
解释：
子数组为 [3]，[1]，[2]，[4]，[3,1]，[1,2]，[2,4]，[3,1,2]，[1,2,4]，[3,1,2,4]。
最小值为 3，1，2，4，1，1，2，1，1，1，和为 17。
示例 2：

输入：arr = [11,81,94,43,3]
输出：444
 *
 *
 * */

int sumSubarrayMins(vector<int> &arr) {

    int n = arr.size();

    vector<int> monoStack;

    vector<int> left(n), right(n);

    for (int i = 0; i < n; i++) {
        while (!monoStack.empty() && arr[i] <= arr[monoStack.back()]) {
            monoStack.pop_back();
        }
        left[i] = i - (monoStack.empty() ? -1 : monoStack.back());
        monoStack.emplace_back(i);
    }

    monoStack.clear();
    for (int i = n - 1; i >= 0; i--) {
        while (!monoStack.empty() && arr[i] < arr[monoStack.back()]) {
            monoStack.pop_back();
        }
        right[i] = (monoStack.empty() ? n : monoStack.back()) - i;
        monoStack.emplace_back(i);
    }
    long long ans = 0;
    long long mod = 1e9 + 7;
    for (int i = 0; i < n; i++) {
        ans = (ans + (long long) left[i] * right[i] * arr[i]) % mod;
    }

    return ans;

}